; Startup code for cc65 and Shiru's NES library
; based on code by Groepaz/Hitmen <groepaz@gmx.net>, Ullrich von Bassewitz <uz@cc65.org>


FT_DPCM_OFF			= $f900		;$c000..$ffc0, 64-byte steps
FT_SFX_STREAMS			= 4		;number of sound effects played at once, 1..4

.define FT_DPCM_ENABLE  1			;undefine to exclude all DMC code
.define FT_SFX_ENABLE   1			;undefine to exclude all sound effects code



	.export _exit,__STARTUP__:absolute=1
	.import initlib,push0,popa,popax,_main,zerobss,copydata

	; Linker generated symbols
	.import __RAM_START__   ,__RAM_SIZE__
	.import __ROM0_START__  ,__ROM0_SIZE__
	.import __STARTUP_LOAD__,__STARTUP_RUN__,__STARTUP_SIZE__
	.import	__CODE_LOAD__   ,__CODE_RUN__   ,__CODE_SIZE__
	.import	__RODATA_LOAD__ ,__RODATA_RUN__ ,__RODATA_SIZE__
	.import NES_MAPPER,NES_PRG_BANKS,NES_CHR_BANKS,NES_MIRRORING

	.include "zeropage.inc"



FT_BASE_ADR		=$0100	;page in RAM, should be $xx00

.define FT_THREAD       1	;undefine if you call sound effects in the same thread as sound update
.define FT_PAL_SUPPORT	1   ;undefine to exclude PAL support
.define FT_NTSC_SUPPORT	1   ;undefine to exclude NTSC support


PPU_CTRL	=$2000
PPU_MASK	=$2001
PPU_STATUS	=$2002
PPU_OAM_ADDR	=$2003
PPU_OAM_DATA	=$2004
PPU_SCROLL	=$2005
PPU_ADDR	=$2006
PPU_DATA	=$2007
PPU_OAM_DMA	=$4014
PPU_FRAMECNT	=$4017
DMC_FREQ	=$4010
CTRL_PORT1	=$4016
CTRL_PORT2	=$4017

OAM_BUF		=$0200
PAL_BUF		=$01c0



.segment "ZEROPAGE"

NTSC_MODE: 		.res 1
FRAME_CNT1: 		.res 1
FRAME_CNT2: 		.res 1
VRAM_UPDATE: 		.res 1
NAME_UPD_ADR: 		.res 2
NAME_UPD_ENABLE: 	.res 1
PAL_UPDATE: 		.res 1
PAL_BG_PTR: 		.res 2
PAL_SPR_PTR: 		.res 2
SCROLL_X: 		.res 1
SCROLL_Y: 		.res 1
SCROLL_X1: 		.res 1
SCROLL_Y1: 		.res 1
PAD_STATE: 		.res 2		;one byte per controller
PAD_STATEP: 		.res 2
PAD_STATET: 		.res 2
PPU_CTRL_VAR:		.res 1
PPU_CTRL_VAR1:		.res 1
PPU_MASK_VAR: 		.res 1
RAND_SEED: 		.res 2
FT_TEMP: 		.res 3

TEMP: 			.res 11

PAD_BUF			=TEMP+1

PTR			=TEMP	;word
LEN			=TEMP+2	;word
NEXTSPR			=TEMP+4
SCRX			=TEMP+5
SCRY			=TEMP+6
SRC			=TEMP+7	;word
DST			=TEMP+9	;word

RLE_LOW			=TEMP
RLE_HIGH		=TEMP+1
RLE_TAG			=TEMP+2
RLE_BYTE		=TEMP+3



.segment "HEADER"

    .byte $4e,$45,$53,$1a
	.byte <NES_PRG_BANKS
	.byte <NES_CHR_BANKS
	.byte <NES_MIRRORING|(<NES_MAPPER<<4)|2
	.byte <NES_MAPPER&$f0
	.res 8,0



.segment "STARTUP"

start:
_exit:

    sei
    ldx #$ff
    txs
    inx
    stx PPU_MASK
    stx DMC_FREQ
    stx PPU_CTRL		;no NMI

initPPU:

    bit PPU_STATUS
@1:
    bit PPU_STATUS
    bpl @1
@2:
    bit PPU_STATUS
    bpl @2

	; MMC3 PRG setup
	lda     #$86
	sta     $8000
	lda     #$00
	sta     $8001

clearPalette:

	lda #$3f
	sta PPU_ADDR
	stx PPU_ADDR
	lda #$0f
	ldx #$20
@1:
	sta PPU_DATA
	dex
	bne @1

clearVRAM:

	txa
	ldy #$20
	sty PPU_ADDR
	sta PPU_ADDR
	ldy #$10
@1:
	sta PPU_DATA
	inx
	bne @1
	dey
	bne @1

clearRAM:

    txa
@1:
    sta $000,x
    sta $100,x
    sta $200,x
    sta $300,x
    sta $400,x
    sta $500,x
    sta $600,x
    sta $700,x
    inx
    bne @1

	lda #4
	jsr _pal_bright
	jsr _pal_clear
	jsr _oam_clear

    jsr	zerobss
	jsr	copydata

    lda #<(__RAM_START__+__RAM_SIZE__)
    sta	sp
    lda	#>(__RAM_START__+__RAM_SIZE__)
    sta	sp+1            ; Set argument stack ptr

	jsr	initlib

	lda #%10000000
	sta <PPU_CTRL_VAR
	sta PPU_CTRL		;enable NMI
	lda #%00000110
	sta <PPU_MASK_VAR

waitSync3:
	lda <FRAME_CNT1
@1:
	cmp <FRAME_CNT1
	beq @1

detectNTSC:
	ldx #52				;blargg's code
	ldy #24
@1:
	dex
	bne @1
	dey
	bne @1

	lda PPU_STATUS
	and #$80
	sta <NTSC_MODE

	jsr _ppu_off

	ldx #<music_data
	ldy #>music_data
	lda <NTSC_MODE
	jsr FamiToneInit

.if(FT_SFX_ENABLE)
	ldx #<sounds_data
	ldy #>sounds_data
	jsr FamiToneSfxInit
.endif

	lda #$fd
	sta <RAND_SEED
	sta <RAND_SEED+1

	lda #0
	sta PPU_SCROLL
	sta PPU_SCROLL
	sta PPU_OAM_ADDR

	jmp _main			;no parameters

	.include "display.sinc"

	.include "neslib.sinc"

.segment "LOWPRG"

music_data:
	.include "music.sinc"

.if(FT_SFX_ENABLE)
sounds_data:
	.include "sounds.sinc"
.endif

.segment "SAMPLES"

.if(FT_DPCM_ENABLE)
	.incbin "music_dpcm.bin"
.endif

.segment "VECTORS"

	.word nmi	;$fffa vblank nmi
	.word start	;$fffc reset
	.word irq	;$fffe irq / brk

; ------------------------------------------------------------------------
; character data
; ------------------------------------------------------------------------

.segment "CHARSPR"
	.incbin	"data/sprites1.chr"
.segment "CHARSPR2"
	.incbin	"data/sprites2.chr"
.segment "CHARBULLETLOGO"
	.incbin	"data/bulletlogo.chr"
.segment "CHARDENIRO0"
	.incbin	"data/deniro_000.chr"
.segment "CHARDENIRO1"
	.incbin	"data/deniro_001.chr"
.segment "CHARDENIRO2"
	.incbin	"data/deniro_002.chr"
.segment "CHARDENIRO3"
	.incbin	"data/deniro_003.chr"
.segment "CHARDENIRO4"
	.incbin	"data/deniro_004.chr"
.segment "CHARDENIRO5"
	.incbin	"data/deniro_005.chr"
.segment "CHARDENIRO6"
	.incbin	"data/deniro_006.chr"
.segment "CHARDENIRO7"
	.incbin	"data/deniro_007.chr"
.segment "CHARDENIRO8"
	.incbin	"data/deniro_008.chr"
.segment "CHARDENIRO9"
	.incbin	"data/deniro_009.chr"
.segment "CHARDENIRO10"
	.incbin	"data/deniro_010.chr"
.segment "CHARDENIRO11"
	.incbin	"data/deniro_011.chr"
.segment "CHARDENIRO12"
	.incbin	"data/deniro_012.chr"
.segment "CHARDENIRO13"
	.incbin	"data/deniro_013.chr"
.segment "CHARDENIRO14"
	.incbin	"data/deniro_014.chr"
.segment "CHARDENIRO15"
	.incbin	"data/deniro_015.chr"
.segment "CHARDENIRO16"
	.incbin	"data/deniro_016.chr"
.segment "CHARDENIRO17"
	.incbin	"data/deniro_017.chr"
.segment "CHARDENIRO18"
	.incbin	"data/deniro_018.chr"
.segment "CHARDENIRO19"
	.incbin	"data/deniro_019.chr"
.segment "CHARDENIRO20"
	.incbin	"data/deniro_020.chr"
.segment "CHARDENIRO21"
	.incbin	"data/deniro_021.chr"
.segment "CHARDENIRO22"
	.incbin	"data/deniro_022.chr"
.segment "CHARDENIRO23"
	.incbin	"data/deniro_023.chr"
.segment "CHARDENIRO24"
	.incbin	"data/deniro_024.chr"
.segment "CHARDENIRO25"
	.incbin	"data/deniro_025.chr"
.segment "CHARDENIRO26"
	.incbin	"data/deniro_026.chr"
.segment "CHARDENIRO27"
	.incbin	"data/deniro_027.chr"
.segment "CHARDENIRO28"
	.incbin	"data/deniro_028.chr"
.segment "CHARDENIRO29"
	.incbin	"data/deniro_029.chr"
.segment "CHARDENIRO30"
	.incbin	"data/deniro_030.chr"
.segment "CHARDENIRO31"
	.incbin	"data/deniro_031.chr"
.segment "CHARDENIRO32"
	.incbin	"data/deniro_032.chr"
.segment "CHARDENIRO33"
	.incbin	"data/deniro_033.chr"
.segment "CHARENT1_0"
	.incbin	"data/entrant1_000.chr"
.segment "CHARENT1_1"
	.incbin	"data/entrant1_001.chr"
.segment "CHARENT1_2"
	.incbin	"data/entrant1_002.chr"
.segment "CHARENT1_3"
	.incbin	"data/entrant1_003.chr"
.segment "CHARENT1_4"
	.incbin	"data/entrant1_004.chr"
.segment "CHARENT1_5"
	.incbin	"data/entrant1_005.chr"
.segment "CHARENT1_6"
	.incbin	"data/entrant1_006.chr"
.segment "CHARENT1_7"
	.incbin	"data/entrant1_007.chr"
.segment "CHARENT1_8"
	.incbin	"data/entrant1_008.chr"
.segment "CHARENT1_9"
	.incbin	"data/entrant1_009.chr"
.segment "CHARENT1_10"
	.incbin	"data/entrant1_010.chr"
.segment "CHARENT1_11"
	.incbin	"data/entrant1_011.chr"
.segment "CHARENT1_12"
	.incbin	"data/entrant1_012.chr"
.segment "CHARENT1_13"
	.incbin	"data/entrant1_013.chr"
.segment "CHARENT1_14"
	.incbin	"data/entrant1_014.chr"
.segment "CHARENT1_15"
	.incbin	"data/entrant1_015.chr"
.segment "CHARENT1_16"
	.incbin	"data/entrant1_016.chr"
.segment "CHARENT1_17"
	.incbin	"data/entrant1_017.chr"
.segment "CHARENT1_18"
	.incbin	"data/entrant1_018.chr"
.segment "CHARENT2_0"
	.incbin	"data/entrant2_000.chr"
.segment "CHARENT2_1"
	.incbin	"data/entrant2_001.chr"
.segment "CHARENT2_2"
	.incbin	"data/entrant2_002.chr"
.segment "CHARENT2_3"
	.incbin	"data/entrant2_003.chr"
.segment "CHARENT2_4"
	.incbin	"data/entrant2_004.chr"
.segment "CHARENT2_5"
	.incbin	"data/entrant2_005.chr"
.segment "CHARENT2_6"
	.incbin	"data/entrant2_006.chr"
.segment "CHARENT2_7"
	.incbin	"data/entrant2_007.chr"
.segment "CHARENT2_8"
	.incbin	"data/entrant2_008.chr"
.segment "CHARENT2_9"
	.incbin	"data/entrant2_009.chr"
.segment "CHARENT2_10"
	.incbin	"data/entrant2_010.chr"
.segment "CHARENT2_11"
	.incbin	"data/entrant2_011.chr"
.segment "CHARENT2_12"
	.incbin	"data/entrant2_012.chr"
.segment "CHARENT2_13"
	.incbin	"data/entrant2_013.chr"
.segment "CHARENT2_14"
	.incbin	"data/entrant2_014.chr"
.segment "CHARENT2_15"
	.incbin	"data/entrant2_015.chr"
.segment "CHARENT2_16"
	.incbin	"data/entrant2_016.chr"
.segment "CHARENT2_17"
	.incbin	"data/entrant2_017.chr"
.segment "CHARENT2_18"
	.incbin	"data/entrant2_018.chr"
.segment "CHARENT2_19"
	.incbin	"data/entrant2_019.chr"
.segment "CHARFONT"
	.incbin	"data/font.chr"
.segment "CHARINTENDON1"
	.incbin	"data/intendon1.chr"
.segment "CHARINTENDON2"
	.incbin	"data/intendon2.chr"
.segment "CHARPRISONER0"
	.incbin	"data/prisoner_000.chr"
.segment "CHARPRISONER1"
	.incbin	"data/prisoner_001.chr"
.segment "CHARPRISONER2"
	.incbin	"data/prisoner_002.chr"
.segment "CHARPRISONER3"
	.incbin	"data/prisoner_003.chr"
.segment "CHARPRISONER4"
	.incbin	"data/prisoner_004.chr"
.segment "CHARPRISONER5"
	.incbin	"data/prisoner_005.chr"
.segment "CHARPRISONER6"
	.incbin	"data/prisoner_006.chr"
.segment "CHARPRISONER7"
	.incbin	"data/prisoner_007.chr"
.segment "CHARPRISONER8"
	.incbin	"data/prisoner_008.chr"
.segment "CHARPRISONER9"
	.incbin	"data/prisoner_009.chr"
.segment "CHARPRISONER10"
	.incbin	"data/prisoner_010.chr"
.segment "CHARPRISONER11"
	.incbin	"data/prisoner_011.chr"
.segment "CHARPRISONER12"
	.incbin	"data/prisoner_012.chr"
.segment "CHARPRISONER13"
	.incbin	"data/prisoner_013.chr"
.segment "CHARPRISONER14"
	.incbin	"data/prisoner_014.chr"
.segment "CHARPRISONER15"
	.incbin	"data/prisoner_015.chr"
.segment "CHARPRISONER16"
	.incbin	"data/prisoner_016.chr"
.segment "CHARPRISONER17"
	.incbin	"data/prisoner_017.chr"
.segment "CHARPRISONER18"
	.incbin	"data/prisoner_018.chr"
.segment "CHARREV0"
	.incbin	"data/rev_000.chr"
.segment "CHARREV1"
	.incbin	"data/rev_001.chr"
.segment "CHARREV2"
	.incbin	"data/rev_002.chr"
.segment "CHARREV3"
	.incbin	"data/rev_003.chr"
.segment "CHARREV4"
	.incbin	"data/rev_004.chr"
.segment "CHARREV5"
	.incbin	"data/rev_005.chr"
.segment "CHARREV6"
	.incbin	"data/rev_006.chr"
.segment "CHARREV7"
	.incbin	"data/rev_007.chr"
.segment "CHARREVOLVER1"
	.incbin	"data/revolver1.chr"
.segment "CHARREVOLVER2"
	.incbin	"data/revolver2.chr"
.segment "CHARROULETTE"
	.incbin	"data/roulette.chr"
.segment "CHARWALKEN0"
	.incbin	"data/walken_000.chr"
.segment "CHARWALKEN1"
	.incbin	"data/walken_001.chr"
.segment "CHARWALKEN2"
	.incbin	"data/walken_002.chr"
.segment "CHARWALKEN3"
	.incbin	"data/walken_003.chr"
.segment "CHARWALKEN4"
	.incbin	"data/walken_004.chr"
.segment "CHARWALKEN5"
	.incbin	"data/walken_005.chr"
.segment "CHARWALKEN6"
	.incbin	"data/walken_006.chr"
.segment "CHARWALKEN7"
	.incbin	"data/walken_007.chr"
.segment "CHARWALKEN8"
	.incbin	"data/walken_008.chr"
.segment "CHARWALKEN9"
	.incbin	"data/walken_009.chr"
.segment "CHARWALKEN10"
	.incbin	"data/walken_010.chr"
.segment "CHARWALKEN11"
	.incbin	"data/walken_011.chr"
.segment "CHARWALKEN12"
	.incbin	"data/walken_012.chr"
.segment "CHARWALKEN13"
	.incbin	"data/walken_013.chr"
.segment "CHARWALKEN14"
	.incbin	"data/walken_014.chr"
.segment "CHARWALKEN15"
	.incbin	"data/walken_015.chr"
.segment "CHARWALKEN16"
	.incbin	"data/walken_016.chr"
.segment "CHARWALKEN17"
	.incbin	"data/walken_017.chr"
.segment "CHARWALKEN18"
	.incbin	"data/walken_018.chr"
.segment "CHARWALKEN19"
	.incbin	"data/walken_019.chr"
.segment "CHARWALKEN20"
	.incbin	"data/walken_020.chr"
.segment "CHARWALKEN21"
	.incbin	"data/walken_021.chr"
.segment "CHARWALKEN22"
	.incbin	"data/walken_022.chr"
.segment "CHARWALKEN23"
	.incbin	"data/walken_023.chr"
.segment "CHARWALKEN24"
	.incbin	"data/walken_024.chr"
.segment "CHARWALKEN25"
	.incbin	"data/walken_025.chr"
.segment "CHARWALKEN26"
	.incbin	"data/walken_026.chr"
.segment "CHARWALKEN27"
	.incbin	"data/walken_027.chr"
.segment "CHARWALKEN28"
	.incbin	"data/walken_028.chr"
.segment "CHARWALKEN29"
	.incbin	"data/walken_029.chr"
.segment "CHARWALKEN30"
	.incbin	"data/walken_030.chr"
.segment "CHARWALKEN31"
	.incbin	"data/walken_031.chr"
.segment "CHARWALKEN32"
	.incbin	"data/walken_032.chr"
.segment "CHARWALKEN33"
	.incbin	"data/walken_033.chr"
.segment "CHARWALKEN34"
	.incbin	"data/walken_034.chr"
.segment "CHARWALKEN35"
	.incbin	"data/walken_035.chr"
.segment "CHAREMPTY"
	.incbin	"data/empty.chr"
.segment "CHARPAD"
	.incbin	"data/pad"
